/**
 * Support script for BeeLine.mxml
 */
import flash.events.MouseEvent;

import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.events.CollectionEvent;
import mx.events.DataGridEvent;
import mx.managers.CursorManager;
import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.HTTPService;

public const ENDPOINT_URL:String = "BeeLine.php";

private var gateway:HTTPService = new HTTPService();

[Bindable]
public var hiveArray:ArrayCollection = new ArrayCollection();
[Bindable]
public var speciesArray:ArrayCollection = new ArrayCollection();
[Bindable]
public var hiveTypeArray:ArrayCollection = new ArrayCollection();

/**
 * column that we order by. This is updated each time the users clicks on the 
 * grid column header. 
 * see headerRelease="setOrder(event);" in the DataGrid instantiation in the 
 * mxml file
 */
private var orderColumn:Number;


/**
 * Callback when "Submit" button is clicked
 */
private function submitFind(eventObj:MouseEvent):void {
	Alert.show("Date of Find="+"\nLongitude="+"\nLatitude\nLocation");
}   


/**
 * the list of fields in the database table
 * needed to parse the response into hashes
 */ 
private var fields:Object = {
	'find_dt':Date,
	'age_years':Number,
	'height':Number, 
	'longitude':Number,
	'latitude':Number,
	'common_name':String,
	'type_name':String
};

private function insertHive():void 
{
    var parameters:* =
    {
        "method": "insert_hive",
        "find_dt": findDateField.text,
        "age_years": ageTextInput.text,  
        "height": heightTextInput.text,
        "hive_type_id": hiveTypeComboBox.selectedLabel,
        "species_id": speciesComboBox.selectedLabel
	};

   doRequest(parameters, insertFindHandler);
}

/**
 * Result handler for the insertFind call.
 * Alert the error if it exists
 * if the call went through ok, return to the list, and refresh the data
 */
private function insertFindHandler(e:Object):void
{
    if (e.isError)
    {
        Alert.show("Error: " + e.data.error);
    }
    else
    {
//        goToView();
//        fill();
    }     
}

private function initBeeLine():void 
{
	m.visible = true;
	
    gateway.url = ENDPOINT_URL;
    gateway.method = "POST";
    gateway.useProxy = false;
    gateway.resultFormat = "e4x";

    gateway.addEventListener(ResultEvent.RESULT, resultHandler);
    gateway.addEventListener(FaultEvent.FAULT, faultHandler);
    
    fillHiveDataGrid();
	fillSpeciesCombo();
}

/**
 * dragHeader handler for the datagrid. This handler is executed when the user 
 * clicks on a header column in the datagrid
 * updates the global orderColumn variable, refreshes the TableCollection
 * @param event DataGridEvent details about the column
 */
private function setOrder(event:DataGridEvent):void 
{
    orderColumn = event.columnIndex;
    var col:DataGridColumn = hiveDataGrid.columns[orderColumn];
    col.sortDescending = !col.sortDescending;
    
    event.preventDefault();
    fillHiveDataGrid();
}

private function fillSpeciesCombo():void
{
    var parameters:* =
    {
        "method": "get_species"
	};

    doRequest(parameters, fillSpeciesComboHandler);
    
}

private function fillSpeciesComboHandler(e:Object):void
{
	m.text += "fillSpeciesComboHandler\n";

    if (e.isError)
    {
        Alert.show("Error: " + e.data.error);
    } 
    else
    {
        speciesArray.removeAll();
        
        for each(var row:XML in e.data.response.row) 
        {
        	speciesArray.addItem({label:row.common_name.toString(), data:row.species_id});
        	m.text += "   " + row + "\n";
        }
    }    
}


/** 
 * general utility function for refreshing the data 
 * gets the filtering and ordering, then dispatches a new server call
 *
 */
private function fillHiveDataGrid():void 
{
    /**
     * find the order parameters
     */
    var desc:Boolean = false;
    var orderField:String = '';
    
    
    
    if(!isNaN(orderColumn))
    {
        var col:DataGridColumn = hiveDataGrid.columns[orderColumn];
        desc = col.sortDescending;
		//remove the 'Col' particle
        orderField = col.dataField.substr(0,col.dataField.length-3);
    }

    hiveDataGrid.enabled = false;
    CursorManager.setBusyCursor();

    var parameters:* =
    {
		"method": "get_hives",
        "orderField": orderField,
        "orderDirection": (desc) ? "DESC" : "ASC"
    }
    doRequest(parameters, fillHiveHandler);
}

private function fillHiveHandler(e:Object):void
{
    if (e.isError)
    {
        Alert.show("Error: " + e.data.error);
    } 
    else
    {
        hiveArray.removeAll();
        for each(var row:XML in e.data.row) 
        {
            var temp:* = {};
            for (var key:String in fields) 
            {
                temp[key] = row[key];
            }

            hiveArray.addItem(temp);
        }

        CursorManager.removeBusyCursor();
        hiveDataGrid.enabled = true;
    }    
}

/**
 * deserializes the xml response
 * handles error cases
 *
 * @param e ResultEvent the server response and details about the connection
 */
public function deserialize(obj:*, e:*):*
{
    var toret:Object = {};
    
    toret.originalEvent = e;

    if (obj.data.elements("error").length() > 0)
    {
        toret.isError = true;
        toret.data = obj.data;
    }
    else
    {
        toret.isError = false;
        toret.metadata = obj.metadata;
        toret.data = obj.data;
    }

    return toret;
}

/**
 * result handler for the gateway
 * deserializes the result, and then calls the REAL event handler
 * (set when making a request in the doRequest function)
 *
 * @param e ResultEvent the server response and details about the connection
 */
public function resultHandler(e:ResultEvent):void
{
    var topass:* = deserialize(e.result, e);
    e.token.handler.call(null, topass);
}

/**
 * fault handler for this connection
 *
 * @param e FaultEvent the error object
 */
public function faultHandler(e:FaultEvent):void
{
	var errorMessage:String = "Connection error: " + e.fault.faultString; 
    if (e.fault.faultDetail) 
    { 
        errorMessage += "\n\nAdditional detail: " + e.fault.faultDetail; 
    } 
    Alert.show(errorMessage);
}

/**
 * makes a request to the server using the gateway instance
 *
 * @param method_name String the method name used in the server dispathcer
 * @param parameters Object name value pairs for sending in post
 * @param callback Function function to be called when the call completes
 */
public function doRequest(parameters:Object, callback:Function):void
{
    gateway.request = parameters;
	
    var call:AsyncToken = gateway.send();
    call.request_params = gateway.request;

    call.handler = callback;
}
